package org.pewpew.client;


import org.pewpew.model.Command;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	private Messenger outboundMesseger;
	private final Messenger inboundMessenger = new Messenger(new IncomingHandler());
	private GameModel gameModel;
	private BroadcastReceiver messageReceiver;
	
	/** Incoming from service **/
	private class IncomingHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			Log.i ("PEW-activity", "Check");			
			switch (msg.what) {
			case Messaging.MSG_UPDATE_WORLD_STATE:
				String worldStateString = msg.getData().getString(Messaging.COMMAND);
				Log.i ("PEW-activity", "Receieved in incoming handler " + worldStateString);
				if (worldStateString != null) {
					//gameModel.updateWorldState (worldStateString);
				}
				else {
					Log.w ("PEW-activity", "Receieved zero string as data");
				}
				break;
			default:
				super.handleMessage(msg);
			}
		}
	}

	private class CommandsReceiever extends BroadcastReceiver {
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (action.equalsIgnoreCase(Messaging.NEW_MESSAGE)) {
				Bundle extra = intent.getExtras();
				String message = extra.getString(Messaging.MESSAGE);
				try {
					Log.i ("PEW-receiever", "Receieved message=" + message);
					gameModel.updateWorldState (message);
				} catch (Exception e) {
					Log.e ("PEW-receiever", e.getMessage(), e);
				}
			}
		}
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		showLoginScreen();
	}

	@Override
	protected void onDestroy() {
		unbindService(serviceConnection);
		unregisterReceiver(messageReceiver);
		super.onDestroy();
	}
	
	private void showLoginScreen() {
		setContentView(R.layout.login);

		Button loginButton = (Button) findViewById(R.id.LoginButton);
		loginButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				TextView loginText = (TextView) findViewById(R.id.LoginTextBox);
				String username = loginText.getText().toString();
				if (username == null || username.length() == 0) {
					return;
				}
				gameModel = new GameModel (username);
			
				showMainScreenAndStartService();
			}
		});
	}

	private void showMainScreenAndStartService() {
		setContentView(R.layout.main);

		setupConsoleListeners();
		setupControlPanel();

		messageReceiver = new CommandsReceiever();
		registerReceiver(messageReceiver, new IntentFilter(Messaging.NEW_MESSAGE));

		bindService(new Intent(this, ControllerPollerService.class), serviceConnection, Context.BIND_AUTO_CREATE);
	}

	private void setupConsoleListeners() {
		//Set up listener for updates
		gameModel.addListener(new ConsoleWorldObserver(this));
		gameModel.addListener(new InfoPanelWorldObserver(this));
	}

	private void setupControlPanel() {
		Button shootButton = (Button) findViewById(R.id.ShootButton);
		shootButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				sendMessageToService(new Command (Messaging.CMD_SHOOT));
			}
		});
	}

	private ServiceConnection serviceConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			outboundMesseger = new Messenger(service);
			try {
				Log.i("PEW-activity", "sending username: " + gameModel.getPlayerName());
				Command command = new Command (Messaging.CMD_SET_USERNAME, gameModel.getPlayerName());
				Message message = Messaging.packToMessage(Messaging.MSG_PROCESS_CLIENT_COMMAND, command.toJSON ());
				message.replyTo = inboundMessenger;
				Log.i("PEW-activity", "replyTo=" + inboundMessenger);
				outboundMesseger.send(message);
			} catch (RemoteException e) {
				Log.w ("PEW-activity", e.getMessage());
			}
		}

		public void onServiceDisconnected(ComponentName className) {
			outboundMesseger = null;
		}
	};

	private void sendMessageToService(Command command) {
		if (outboundMesseger != null) {
			try {
				Message msg = Messaging.packToMessage(Messaging.MSG_PROCESS_CLIENT_COMMAND, command.toJSON ());
				msg.replyTo = inboundMessenger;
				outboundMesseger.send(msg);
			} catch (RemoteException e) {
			}
		}
	}
}
